#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <ctime>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <filesystem>
#include <functional>
#include <thread>
#include <mutex>
#include <atomic>
#include <unordered_map>
#include <chrono>
#include <iomanip>
#include <cstring>
#include <codecvt>
#include <locale>
#include <sys/stat.h> // 添加系统头文件

#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <direct.h>   // 添加Windows目录操作头文件
#pragma warning(disable:4244)
#pragma warning(disable:4267)
#pragma warning(disable:4996)
#pragma comment(lib, "ws2_32.lib")
#else
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif

using namespace std;
using namespace std::chrono;

// ======================== INI文件读写模块 ========================
class INIReader {
public:
    bool parse(const string& filename) {
        ifstream file(filename);
        if (!file.is_open()) return false;

        string line;
        string currentSection;

        while (getline(file, line)) {
            line = trim(line);
            if (line.empty() || line[0] == ';' || line[0] == '#') continue;

            if (line[0] == '[' && line.back() == ']') {
                currentSection = line.substr(1, line.size() - 2);
            }
            else {
                size_t equalsPos = line.find('=');
                if (equalsPos != string::npos) {
                    string key = trim(line.substr(0, equalsPos));
                    string value = trim(line.substr(equalsPos + 1));
                    data[currentSection][key] = value;
                }
            }
        }
        return true;
    }

    string get(const string& section, const string& key, const string& default_value = "") {
        if (data.find(section) != data.end()) {
            auto& sectionData = data[section];
            if (sectionData.find(key) != sectionData.end()) {
                return sectionData[key];
            }
        }
        return default_value;
    }

    void set(const string& section, const string& key, const string& value) {
        data[section][key] = value;
    }

    bool save(const string& filename) {
        ofstream file(filename);
        if (!file.is_open()) return false;

        // 修改为传统迭代方式
        for (const auto& sectionEntry : data) {
            const string& section = sectionEntry.first;
            const auto& kv = sectionEntry.second;
            file << "[" << section << "]\n";
            for (const auto& keyValue : kv) {
                const string& key = keyValue.first;
                const string& value = keyValue.second;
                file << key << " = " << value << "\n";
            }
            file << "\n";
        }
        return true;
    }

    vector<string> getSections() const {
        vector<string> sections;
        for (const auto& sectionEntry : data) {
            sections.push_back(sectionEntry.first);
        }
        return sections;
    }

    vector<string> getKeys(const string& section) const {
        vector<string> keys;
        if (data.find(section) != data.end()) {
            const auto& sectionData = data.at(section);
            for (const auto& keyEntry : sectionData) {
                keys.push_back(keyEntry.first);
            }
        }
        return keys;
    }

private:
    unordered_map<string, unordered_map<string, string>> data;

    string trim(const string& str) {
        size_t first = str.find_first_not_of(" \t");
        if (first == string::npos) return "";
        size_t last = str.find_last_not_of(" \t");
        return str.substr(first, (last - first + 1));
    }
};

// ======================== HTTP服务器模块 ========================
class HTTPServer {
public:
    using Handler = function<string(const unordered_map<string, string>&, const string&)>;

    HTTPServer(int port) : port(port), running(false) {}

    void addHandler(const string& path, Handler handler) {
        handlers[path] = handler;
    }

    void start() {
        running = true;
#ifdef _WIN32
        WSADATA wsaData;
        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
            cerr << "WSAStartup failed\n";
            return;
        }
#endif

        serverSocket = socket(AF_INET, SOCK_STREAM, 0);
        if (serverSocket < 0) {
            cerr << "Error creating socket\n";
            return;
        }

        sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_addr.s_addr = INADDR_ANY;
        serverAddr.sin_port = htons(port);

        /*if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
            cerr << "Binding failed\n";
            return;
        }*/

        if (listen(serverSocket, 5) < 0) {
            cerr << "Listen failed\n";
            return;
        }

        cout << "人事管理系统已启动: http://localhost:" << port << "\n";

        while (running) {
            sockaddr_in clientAddr;
            socklen_t clientLen = sizeof(clientAddr);
            int clientSocket = accept(serverSocket, (struct sockaddr*)&clientAddr, &clientLen);
            if (clientSocket < 0) {
                cerr << "Accept failed\n";
                continue;
            }

            handleRequest(clientSocket);
#ifdef _WIN32
            closesocket(clientSocket);
#else
            close(clientSocket);
#endif
        }

#ifdef _WIN32
        closesocket(serverSocket);
        WSACleanup();
#else
        close(serverSocket);
#endif
    }

    void stop() {
        running = false;
    }

private:
    int port;
    int serverSocket;
    atomic<bool> running;
    unordered_map<string, Handler> handlers;

    void handleRequest(int clientSocket) {
        char buffer[4096] = { 0 };
        recv(clientSocket, buffer, sizeof(buffer), 0);

        string request(buffer);
        istringstream iss(request);
        string method, path;
        iss >> method >> path;

        // 解析查询参数
        unordered_map<string, string> params;
        size_t qpos = path.find('?');
        if (qpos != string::npos) {
            string query = path.substr(qpos + 1);
            path = path.substr(0, qpos);

            size_t start = 0;
            while (start < query.size()) {
                size_t end = query.find('&', start);
                if (end == string::npos) end = query.size();
                string pair = query.substr(start, end - start);
                size_t eq = pair.find('=');
                if (eq != string::npos) {
                    string key = urlDecode(pair.substr(0, eq));
                    string value = urlDecode(pair.substr(eq + 1));
                    params[key] = value;
                }
                start = end + 1;
            }
        }

        // 处理POST请求体
        string body;
        size_t contentPos = request.find("Content-Length: ");
        if (contentPos != string::npos) {
            contentPos += 16;
            size_t endPos = request.find("\r\n", contentPos);
            if (endPos != string::npos) {
                int length = stoi(request.substr(contentPos, endPos - contentPos));
                size_t bodyPos = request.find("\r\n\r\n");
                if (bodyPos != string::npos && bodyPos + 4 + length <= request.size()) {
                    body = request.substr(bodyPos + 4, length);
                }
            }
        }

        // 处理请求
        string responseContent;
        if (handlers.find(path) != handlers.end()) {
            try {
                responseContent = handlers[path](params, body);
            }
            catch (const exception& e) {
                responseContent = "Error: " + string(e.what());
            }
        }
        else if (path == "/" || path == "/index.html") {
            responseContent = serveStatic("index.html");
        }
        else if (path == "/api" || path == "/api/") {
            responseContent = "{\"status\":\"API endpoint\"}";
        }
        else {
            responseContent = serveStatic(path);
        }

        ostringstream oss;
        oss << "HTTP/1.1 200 OK\r\n";
        oss << "Content-Type: " << getContentType(path) << "; charset=utf-8\r\n";
        oss << "Content-Length: " << responseContent.size() << "\r\n";
        oss << "Connection: close\r\n";
        oss << "\r\n";
        oss << responseContent;

        string response = oss.str();
        send(clientSocket, response.c_str(), response.size(), 0);
    }

    string serveStatic(const string& path) {
        if (path == "/index.html" || path == "index.html" || path == "/") {
            // 返回嵌入式HTML文件内容
            return R"(
                <!-- 此处嵌入前端HTML代码 -->
            )";
        }
        return "File not found: " + path;
    }

    string urlDecode(const string& str) {
        string result;
        for (size_t i = 0; i < str.size(); i++) {
            if (str[i] == '+') {
                result += ' ';
            }
            else if (str[i] == '%' && i + 2 < str.size()) {
                int hex = stoi(str.substr(i + 1, 2), nullptr, 16);
                result += static_cast<char>(hex);
                i += 2;
            }
            else {
                result += str[i];
            }
        }
        return result;
    }

    string getContentType(const string& path) {
        if (path.find(".css") != string::npos) return "text/css";
        if (path.find(".js") != string::npos) return "application/javascript";
        if (path.find(".png") != string::npos) return "image/png";
        if (path.find(".jpg") != string::npos) return "image/jpeg";
        return "text/html";
    }
};

// ======================== RBAC权限系统 ========================
class RBAC {
public:
    enum class Role { ADMIN, STAFF };

    void initialize() {
        // 定义权限规则
        roles[Role::ADMIN] = {
            {"attendance", "*"},
            {"salary", "*"},
            {"employee", "*"},
            {"config", "*"},
            {"report", "*"}
        };

        roles[Role::STAFF] = {
            {"attendance", "view"},
            {"attendance", "edit"},
            {"salary", "view"}
        };
    }

    bool hasPermission(Role role, const string& resource, const string& action) {
        if (role == Role::ADMIN) return true;

        for (const auto& perm : roles[role]) {
            if (perm.resource == resource &&
                (perm.action == "*" || perm.action == action)) {
                return true;
            }
        }
        return false;
    }

private:
    struct Permission {
        string resource;
        string action;
    };
    unordered_map<Role, vector<Permission>> roles;
};

// ======================== 考勤系统 ========================
class AttendanceSystem {
public:
    struct AttendanceRecord {
        string date;
        string checkIn;
        string checkOut;
        int overtime = 0; // 加班分钟数
        string status; // "present", "late", "absent"
        string attachment; // 附件文件名
    };

    bool load(const string& employeeId) {
        INIReader reader;
        if (!reader.parse("attendance.ini")) return false;

        records.clear();
        vector<string> keys = reader.getKeys(employeeId);
        for (const auto& key : keys) {
            if (key.find("record_") == 0) {
                AttendanceRecord record;
                record.date = key.substr(7);
                string value = reader.get(employeeId, key);
                size_t pos1 = value.find('|');
                size_t pos2 = value.find('|', pos1 + 1);
                size_t pos3 = value.find('|', pos2 + 1);
                size_t pos4 = value.find('|', pos3 + 1);

                if (pos1 != string::npos) record.checkIn = value.substr(0, pos1);
                if (pos2 != string::npos) record.checkOut = value.substr(pos1 + 1, pos2 - pos1 - 1);
                if (pos3 != string::npos) record.overtime = stoi(value.substr(pos2 + 1, pos3 - pos2 - 1));
                if (pos4 != string::npos) record.status = value.substr(pos3 + 1, pos4 - pos3 - 1);
                if (pos4 != string::npos) record.attachment = value.substr(pos4 + 1);

                records.push_back(record);
            }
        }
        return true;
    }

    bool save(const string& employeeId) {
        INIReader reader;
        reader.parse("attendance.ini");

        // 清除旧记录
        vector<string> keys = reader.getKeys(employeeId);
        for (const auto& key : keys) {
            if (key.find("record_") == 0) {
                reader.set(employeeId, key, "");
            }
        }

        // 保存新记录
        for (size_t i = 0; i < records.size(); i++) {
            const auto& record = records[i];
            string key = "record_" + record.date;
            string value = record.checkIn + "|" + record.checkOut + "|" +
                to_string(record.overtime) + "|" + record.status + "|" +
                record.attachment;
            reader.set(employeeId, key, value);
        }
        return reader.save("attendance.ini");
    }

    void checkIn(const string& employeeId) {
        time_t now = time(nullptr);
        tm* local = localtime(&now);

        AttendanceRecord record;
        record.date = formatDate(*local);
        record.checkIn = formatTime(*local);

        // 判断是否迟到 (9:00为标准)
        if (local->tm_hour > 9 || (local->tm_hour == 9 && local->tm_min > 0)) {
            record.status = "late";
        }
        else {
            record.status = "present";
        }

        records.push_back(record);
        save(employeeId);
    }

    void checkOut(const string& employeeId) {
        if (records.empty()) return;

        time_t now = time(nullptr);
        tm* local = localtime(&now);

        records.back().checkOut = formatTime(*local);
        save(employeeId);
    }

    void applyOvertime(const string& employeeId, int minutes, const string& attachment = "") {
        if (records.empty()) return;

        records.back().overtime = minutes;
        if (!attachment.empty()) {
            records.back().attachment = attachment;
        }
        save(employeeId);
    }

    vector<AttendanceRecord> getRecords() const {
        return records;
    }

    vector<AttendanceRecord> getRecordsByMonth(const string& yearMonth) const {
        vector<AttendanceRecord> result;
        for (const auto& record : records) {
            if (record.date.substr(0, 7) == yearMonth) {
                result.push_back(record);
            }
        }
        return result;
    }

private:
    vector<AttendanceRecord> records;

    string formatDate(const tm& time) {
        char buffer[11];
        strftime(buffer, sizeof(buffer), "%Y-%m-%d", &time);
        return buffer;
    }

    string formatTime(const tm& time) {
        char buffer[9];
        strftime(buffer, sizeof(buffer), "%H:%M:%S", &time);
        return buffer;
    }
};

// ======================== 薪资系统 ========================
class SalarySystem {
public:
    struct SalaryRecord {
        string date; // 年月
        double baseSalary;
        double fullAttendanceBonus;
        double overtimePay;
        double totalSalary;
    };

    double calculateSalary(const string& employeeId, const AttendanceSystem& attendance) {
        const double dailySalary = 200.0; // 日薪
        const double hourlyRate = 25.0;   // 时薪
        const double fullAttendanceBonus = 500.0; // 全勤奖

        time_t now = time(nullptr);
        tm* local = localtime(&now);
        string currentMonth = formatMonth(*local);

        double baseSalary = 0.0;
        int attendanceDays = 0;
        double overtimeHours = 0.0;

        vector<AttendanceSystem::AttendanceRecord> records = attendance.getRecordsByMonth(currentMonth);

        for (const auto& record : records) {
            if (record.status != "absent") {
                attendanceDays++;

                // 计算工作时长
                if (!record.checkIn.empty() && !record.checkOut.empty()) {
                    // 替换strptime为get_time
                    tm inTm = {}, outTm = {};
                    istringstream inStream(record.checkIn);
                    istringstream outStream(record.checkOut);

                    inStream >> get_time(&inTm, "%H:%M:%S");
                    outStream >> get_time(&outTm, "%H:%M:%S");

                    // 确保时间解析正确
                    if (inStream.fail() || outStream.fail()) continue;

                    time_t inTime = mktime(&inTm);
                    time_t outTime = mktime(&outTm);
                    double hours = difftime(outTime, inTime) / 3600.0;
                    if (hours > 8) {
                        overtimeHours += (hours - 8);
                    }
                }
            }
            overtimeHours += record.overtime / 60.0;
        }

        baseSalary = attendanceDays * dailySalary;
        double overtimePay = overtimeHours * hourlyRate * 1.5; // 加班补贴1.5倍

        SalaryRecord record;
        record.date = currentMonth;
        record.baseSalary = baseSalary;
        record.overtimePay = overtimePay;
        record.fullAttendanceBonus = (attendanceDays >= 22) ? fullAttendanceBonus : 0.0;
        record.totalSalary = record.baseSalary + record.overtimePay + record.fullAttendanceBonus;

        // 保存记录
        salaries.push_back(record);
        save(employeeId);

        return record.totalSalary;
    }

private:
    vector<SalaryRecord> salaries;

    string formatMonth(const tm& time) {
        char buffer[8];
        strftime(buffer, sizeof(buffer), "%Y-%m", &time);
        return buffer;
    }

    void save(const string& employeeId) {
        // 实际保存到文件系统或数据库的逻辑
    }
};

// ======================== 文件控制器 ========================
class FileController {
public:
    static bool upload(const string& employeeId, const string& date, const string& filename, const string& content) {
        // 创建目录
        string dir = "uploads/" + employeeId;
        if (!fs::exists(dir)) {
            fs::create_directories(dir);
        }

        // 创建文件
        ofstream file(dir + "/" + date + "_" + filename, ios::binary);
        if (!file.is_open()) return false;
        file.write(content.c_str(), content.size());
        return true;
    }

    static string download(const string& employeeId, const string& filename) {
        string path = "uploads/" + employeeId + "/" + filename;
        ifstream file(path, ios::binary);
        if (!file.is_open()) return "";

        ostringstream oss;
        oss << file.rdbuf();
        return oss.str();
    }

private:
    // 文件系统辅助类
    struct fs {
        static bool exists(const string& path) {
            struct stat buffer;
            return (stat(path.c_str(), &buffer) == 0);
        }

        static bool create_directories(const string& path) {
            string dir;
            size_t pos = 0;
            while ((pos = path.find_first_of("/\\", pos + 1)) != string::npos) {
                dir = path.substr(0, pos);
                mkdir(dir.c_str());
            }
            mkdir(path.c_str());
            return true;
        }
    };

    static int mkdir(const char* path) {
#ifdef _WIN32
        return _mkdir(path);
#else
        return ::mkdir(path, 0755);
#endif
    }
};

// ======================== 主系统 ========================
class HRSystem {
public:
    HRSystem() {
        rbac.initialize();
        loadEmployees();
    }

    bool login(const string& username, const string& password) {
        string storedPass = employeeDB.get(username, "password", "");
        if (storedPass == password) {
            currentUser = username;
            currentRole = (employeeDB.get(username, "role", "staff") == "admin") ?
                RBAC::Role::ADMIN : RBAC::Role::STAFF;
            return true;
        }
        return false;
    }

    void loadEmployees() {
        employeeDB.parse("employees.ini");
    }

    bool hasPermission(const string& resource, const string& action) {
        return rbac.hasPermission(currentRole, resource, action);
    }

    string getCurrentUser() const {
        return currentUser;
    }

    RBAC::Role getCurrentRole() const {
        return currentRole;
    }

    // 考勤操作
    void checkIn() {
        if (currentUser.empty()) return;
        attendance.load(currentUser);
        attendance.checkIn(currentUser);
    }

    void checkOut() {
        if(currentUser.empty()) return;
        attendance.load(currentUser);
        attendance.checkOut(currentUser);
    }

    void applyOvertime(int minutes, const string& attachment = "") {
        if (currentUser.empty()) return;
        attendance.load(currentUser);
        attendance.applyOvertime(currentUser, minutes, attachment);
    }

    // 获取考勤记录
    vector<AttendanceSystem::AttendanceRecord> getAttendanceRecords() {
        if (currentUser.empty()) return {};
        attendance.load(currentUser);
        return attendance.getRecords();
    }

    // 计算工资
    double calculateSalary() {
        if (currentUser.empty()) return 0.0;
        attendance.load(currentUser);
        return salarySystem.calculateSalary(currentUser, attendance);
    }

private:
    RBAC rbac;
    INIReader employeeDB;
    string currentUser;
    RBAC::Role currentRole;
    AttendanceSystem attendance;
    SalarySystem salarySystem;
};

// ======================== 主函数 ========================
int main() {
    // 初始化HR系统
    HRSystem hrSystem;

    // 创建HTTP服务器
    HTTPServer server(8080);

    // 注册API处理函数
    server.addHandler("/api/login", [&](const unordered_map<string, string>& params, const string& body) -> string {
        string username = params.count("username") ? params.at("username") : "";
        string password = params.count("password") ? params.at("password") : "";

        if (hrSystem.login(username, password)) {
            // 修复此处：显式转换为string
            string role = (hrSystem.getCurrentRole() == RBAC::Role::ADMIN) ? "admin" : "staff";
            return "{\"success\": true, \"role\": \"" + role + "\"}";
        }
        return "{\"success\": false}";
        });

    server.addHandler("/api/checkin", [&](const unordered_map<string, string>& params, const string& body) -> string {
        hrSystem.checkIn();
        return "{\"success\": true}";
        });

    server.addHandler("/api/checkout", [&](const unordered_map<string, string>& params, const string& body) -> string {
        hrSystem.checkOut();
        return "{\"success\": true}";
        });

    server.addHandler("/api/overtime", [&](const unordered_map<string, string>& params, const string& body) -> string {
        int minutes = params.count("minutes") ? stoi(params.at("minutes")) : 0;
        hrSystem.applyOvertime(minutes);
        return "{\"success\": true}";
        });

    // 修复此处：body�� 改为 body
    server.addHandler("/api/attendance", [&](const unordered_map<string, string>& params, const string& body) -> string {
        auto records = hrSystem.getAttendanceRecords();
        ostringstream json;
        json << "[";
        for (size_t i = 0; i < records.size(); i++) {
            const auto& r = records[i];
            json << "{";
            json << "\"date\":\"" << r.date << "\",";
            json << "\"checkIn\":\"" << r.checkIn << "\",";
            json << "\"checkOut\":\"" << r.checkOut << "\",";
            json << "\"overtime\":" << r.overtime << ",";
            json << "\"status\":\"" << r.status << "\",";
            json << "\"attachment\":\"" << r.attachment << "\"";
            json << "}";
            if (i < records.size() - 1) json << ",";
        }
        json << "]";
        return json.str();
        });

    server.addHandler("/api/salary", [&](const unordered_map<string, string>& params, const string& body) -> string {
        double salary = hrSystem.calculateSalary();
        return "{\"salary\":" + to_string(salary) + "}";
        });

    // 启动服务器
    server.start();
    system("pause");
    return 0;
}